<template>
  <view class="content">
    <!-- 聊天消息区域 -->
    <scroll-view class="chat-body" :scroll-y="true" :scroll-with-animation="true" :scroll-top="scrollTop"
      @scrolltoupper="loadMoreMessages">
      <view v-for="msg in messages" :key="msg.id" :class="['chat-message', msg.isMe ? 'me' : 'bot']">
        <image :src="msg.avatar" class="chat-avatar" v-if="!msg.isMe" />
        <view class="chat-bubble" :class="msg.isMe ? 'bubble-me' : 'bubble-bot'">
          <text>{{ msg.text }}</text>
        </view>
        <image :src="msg.avatar" class="chat-avatar" v-if="msg.isMe" />
      </view>
    </scroll-view>

    <!-- 输入区域 -->
    <view class="chat-input-float">
      <view class="chat-input-bar">
        <view class="chat-input-wrap">
          <input v-model="inputText" class="chat-input" type="text" placeholder="请输入消息" @keyup.enter="handleSend"
            :disabled="isLoading" />
        </view>
        <button class="send-btn" @click="handleSend" :disabled="isLoading || !inputText.trim()">
          {{ isLoading ? '发送中...' : '发送' }}
        </button>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  data() {
    return {
      messages: [
        {
          id: 1,
          avatar: '/static/logo.png',
          text: '欢迎使用聊天功能！',
          isMe: false
        }
      ],
      inputText: '',
      scrollTop: 0,
      api_key: '',
      currentSession: {
        id: '',
        name: '聊天助手'
      },
      isLoading: false,
      xhr: null,
      buffer: '',
      retryCount: 0,
      maxRetries: 3,
      timeoutDuration: 30000,
      typingSpeed: 50, // 打字速度（毫秒）
      isTyping: false, // 是否正在打字
      typingQueue: [], // 打字队列
      currentTypingMessage: null // 当前正在打字的消息
    }
  },

  onLoad() {
    this.getApiKey()
  },

  onUnload() {
    this.cleanupConnection()
  },

  methods: {
    // 获取API密钥
    getApiKey() {
      try {
        const appPages = getCurrentPages()
        const appCurrentPage = appPages[appPages.length - 1]
        if (appCurrentPage?.$page?.options?.api_key) {
          this.api_key = appCurrentPage.$page.options.api_key
        } else {
          const options = uni.getLaunchOptionsSync()
          this.api_key = options.query?.api_key || ''
        }

        if (!this.api_key) {
          this.showError('未获取到API密钥')
        }
      } catch (error) {
        console.error('获取api_key失败:', error)
        this.showError('获取API密钥失败')
      }
    },

    // 发送消息
    async handleSend() {
      if (this.isLoading || !this.inputText.trim()) {
        return
      }

      try {
        this.isLoading = true

        // 添加用户消息
        const userMessage = {
          id: Date.now(),
          avatar: '/static/logo.png',
          text: this.inputText,
          isMe: true
        }
        this.messages.push(userMessage)
        this.scrollToBottom()

        // 保存并清空输入
        const userInput = this.inputText
        this.inputText = ''

        // 添加AI思考消息
        const loadingMessage = {
          id: 'loading_' + Date.now(),
          avatar: '/static/logo.png',
          text: 'AI 正在思考...',
          isMe: false
        }
        this.messages.push(loadingMessage)

        // 发送请求
        await this.sendRequest(userInput)
      } catch (error) {
        console.error('发送消息失败:', error)
        this.showError(error.message || '发送失败，请重试')
      } finally {
        this.isLoading = false
      }
    },

    // 发送请求
    sendRequest(userInput) {
      return new Promise((resolve, reject) => {
        this.cleanupConnection()
        this.buffer = ''
        this.retryCount = 0

        const connect = () => {
          try {
            this.xhr = new plus.net.XMLHttpRequest()

            this.xhr.open('POST', 'http://jfjk.stardust2000.com:10245/v1/chat-messages')
            this.xhr.setRequestHeader('Content-Type', 'application/json')
            this.xhr.setRequestHeader('Authorization', 'Bearer app-HPGdZ7BR1EsVVFW5CUT8ubUD')
            this.xhr.setRequestHeader('Accept', 'text/event-stream')
            this.xhr.responseType = 'text'
            this.xhr.timeout = this.timeoutDuration

            // 状态变化处理
            this.xhr.onreadystatechange = () => {
              console.log('状态变化:', this.xhr.readyState)
              if (this.xhr.readyState >= 3) {
                try {
                  const responseText = this.xhr.responseText
                  if (responseText) {
                    const newData = responseText.slice(this.buffer.length)
                    if (newData) {
                      this.buffer = responseText
                      this.processStreamData(newData)
                    }
                  }
                } catch (error) {
                  console.error('处理响应数据失败:', error)
                }
              }

              if (this.xhr.readyState === 4) {
                if (this.xhr.status === 200) {
                  resolve()
                } else {
                  reject(new Error('HTTP错误: ' + this.xhr.status))
                }
              }
            }

            // 错误处理
            this.xhr.onerror = () => {
              if (this.retryCount < this.maxRetries) {
                this.retryCount++
                console.log('连接失败，第 ' + this.retryCount + ' 次重试')
                connect()
              } else {
                reject(new Error('网络连接失败'))
              }
            }

            // 超时处理
            this.xhr.ontimeout = () => {
              if (this.retryCount < this.maxRetries) {
                this.retryCount++
                console.log('请求超时，第 ' + this.retryCount + ' 次重试')
                connect()
              } else {
                reject(new Error('请求超时'))
              }
            }

            // 发送请求
            const requestBody = {
              inputs: {},
              query: userInput,
              response_mode: "streaming",
              conversation_id: this.currentSession.id || "",
              user: 123
            }

            this.xhr.send(JSON.stringify(requestBody))
          } catch (error) {
            reject(new Error('发送请求失败: ' + error.message))
          }
        }

        connect()
      })
    },

    // 处理流式数据
    processStreamData(data) {
      console.log('处理流式数据:', data)
      try {
        const lines = data.split('\n\n')

        for (const line of lines) {
          if (!line.trim()) continue

          if (line.startsWith('data: ')) {
            try {
              const jsonStr = line.slice(6)
              const data = JSON.parse(jsonStr)

              if (data.event === 'message' && data.answer) {
                // 将新数据添加到打字队列
                this.addToTypingQueue(data.answer)
              }
            } catch (e) {
              console.error('解析消息数据失败:', e)
            }
          }
        }
      } catch (error) {
        console.error('处理流数据失败:', error)
      }
    },

    // 添加到打字队列
    addToTypingQueue(text) {
      if (!this.currentTypingMessage) {
        // 获取最后一条消息
        const lastMsg = this.messages[this.messages.length - 1]
        if (lastMsg.text === 'AI 正在思考...') {
          lastMsg.text = ''
        }
        this.currentTypingMessage = lastMsg
      }

      // 将文本分割成字符数组
      const chars = text.split('')
      this.typingQueue.push(...chars)

      // 如果当前没有在打字，开始打字
      if (!this.isTyping) {
        this.startTyping()
      }
    },

    // 开始打字效果
    startTyping() {
      if (this.isTyping || this.typingQueue.length === 0) return

      this.isTyping = true
      this.typeNextChar()
    },

    // 打下一个字符
    typeNextChar() {
      if (this.typingQueue.length === 0) {
        this.isTyping = false
        this.currentTypingMessage = null
        return
      }

      const char = this.typingQueue.shift()
      if (this.currentTypingMessage) {
        this.currentTypingMessage.text += char
        this.scrollToBottom()
      }

      // 继续打下一个字符
      setTimeout(() => {
        this.typeNextChar()
      }, this.typingSpeed)
    },

    // 清理连接
    cleanupConnection() {
      if (this.xhr) {
        this.xhr.abort()
        this.xhr = null
      }
      // 清理打字状态
      this.isTyping = false
      this.typingQueue = []
      this.currentTypingMessage = null
    },

    // 显示错误信息
    showError(message) {
      uni.showToast({
        title: message,
        icon: 'none',
        duration: 2000
      })
    },

    // 滚动到底部
    scrollToBottom() {
      setTimeout(() => {
        const query = uni.createSelectorQuery()
        query.select('.chat-body').boundingClientRect()
        query.selectAll('.chat-message').boundingClientRect()
        query.exec(res => {
          if (res?.[0] && res?.[1]) {
            const totalHeight = res[1].reduce((sum, msg) => sum + (msg.height || 0), 0)
            this.scrollTop = totalHeight
          }
        })
      }, 100)
    },

    // 加载更多消息（预留）
    loadMoreMessages() {
      // TODO: 实现历史消息加载
      console.log('加载更多消息')
    }
  }
}
</script>

<style>
.content {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background: #f7f8fa;
}

.chat-body {
  flex: 1;
  padding: 20px;
  box-sizing: border-box;
}

.chat-message {
  display: flex;
  align-items: flex-start;
  margin-bottom: 20px;
}

.chat-message.bot {
  justify-content: flex-start;
}

.chat-message.me {
  justify-content: flex-end;
}

.chat-avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  margin: 0 10px;
  flex-shrink: 0;
}

.chat-bubble {
  max-width: 70%;
  padding: 12px 16px;
  border-radius: 4px 16px 16px 16px;
  font-size: 15px;
  line-height: 1.4;
  word-break: break-word;
}

.bubble-bot {
  background: #fff;
  color: #333;
  margin-left: 0;
  margin-right: 10px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.bubble-me {
  background: #1976d2;
  color: #fff;
  border-radius: 16px 4px 16px 16px;
  margin-right: 0;
  margin-left: 10px;
}

.chat-input-float {
  background: #fff;
  padding: 12px 16px;
  box-shadow: 0 -2px 16px rgba(0, 0, 0, 0.08);
  position: relative;
  z-index: 10;
}

.chat-input-bar {
  display: flex;
  align-items: center;
  gap: 10px;
}

.chat-input-wrap {
  flex: 1;
  display: flex;
  align-items: center;
  min-height: 40px;
  padding: 0 12px;
  background: #f5f5f5;
  border-radius: 8px;
}

.chat-input {
  width: 100%;
  border: none;
  outline: none;
  background: transparent;
  font-size: 15px;
  height: 40px;
  line-height: 40px;
}

.send-btn {
  background: #1976d2;
  color: #fff;
  border-radius: 8px;
  font-size: 15px;
  padding: 0 20px;
  height: 40px;
  line-height: 40px;
  border: none;
  white-space: nowrap;
}

.send-btn:disabled {
  background: #ccc;
  cursor: not-allowed;
}
</style>
